/**
 * $RCSfile: ,v $
 * $Revision: $
 * $Date: $
 * 
 * Copyright (C) 2004-2011 Jive Software. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.dkbrazz.sparkplug;

import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.Timer;

import org.jivesoftware.resource.SparkRes;
import org.jivesoftware.smackx.packet.VCard;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.UserManager;
import org.jivesoftware.spark.util.ModelUtil;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.spark.util.log.Log;

/**
 * UI to display VCard Information in Wizards, Dialogs, Chat Rooms and any other container.
 *
 * @author Derek DeMoro, Denis Kurochkin
 */
public class VCardPanelExt extends JPanel {

   /**
	 * 
	 */
	private static final long serialVersionUID = 3649591069763119033L;
    private JWindow _avatarHoverWindow = new JWindow();
    private final String jid;
    private final JLabel avatarImage;

    /**
     * Generate a VCard Panel using the specified jid.
     *
     * @param jid the jid to use when retrieving the vcard information.
     */
    public VCardPanelExt(final String jid) {
        setLayout(new GridBagLayout());
        setOpaque(false);

        this.jid = jid;
        avatarImage = new JLabel();
        add(avatarImage, new GridBagConstraints(0, 0, 1, 6, 0.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 0), 0, 0));
        buildAvatarHover();

        Image aImage = SparkRes.getImageIcon(SparkRes.BLANK_24x24).getImage();
        aImage = aImage.getScaledInstance(-1, 64, Image.SCALE_SMOOTH);
        ImageIcon ico = new ImageIcon(aImage);

        avatarImage.setIcon(ico);

        VCard vcard = SparkManager.getVCardManager().getVCard(jid);

        if (vcard == null) {
            // Do nothing.
            return;
        }

        ImageIcon icon = null;

        byte[] bytes = vcard.getAvatar();
        if (bytes != null && bytes.length > 0) {
            try {
                icon = new ImageIcon(bytes);
                Image newImage = icon.getImage();
                if (icon.getIconHeight() > 48 || icon.getIconWidth() > 48) {
                newImage = newImage.getScaledInstance(-1, 48, Image.SCALE_SMOOTH);
                }
                icon = new ImageIcon(newImage);
            }
            catch (Exception e) {
                Log.error(e);
            }
        }
        else {
            icon = SparkRes.getImageIcon(SparkRes.DEFAULT_AVATAR_32x32_IMAGE);
        }

        if (icon != null && icon.getIconWidth() > 0) {
            avatarImage.setIcon(icon);
            avatarImage.setBorder(BorderFactory.createBevelBorder(0, Color.white, Color.lightGray));
        }

        vcard.setJabberId(jid);
        buildUI(vcard);
    }
    
    
    private void buildAvatarHover() {
        _avatarHoverWindow.addMouseListener(new MouseAdapter() {
            public void mouseExited(MouseEvent e) {
                showAvatarBig(false, null);

            };
        });

    }

    private void showAvatarBig(boolean bool, VCard vcard) {
        if (bool && !_avatarHoverWindow.isVisible()) {

            _avatarHoverWindow.setLocation(avatarImage.getLocationOnScreen().x+2,avatarImage.getLocationOnScreen().y+2);
            _avatarHoverWindow.setVisible(true);
            ImageIcon icon = null;
            JLabel label = new JLabel();
            _avatarHoverWindow.add(label);
            byte[] bytes = vcard.getAvatar();
            Image newImage = null;
            if (bytes != null && bytes.length > 0) {
                try {
                    icon = new ImageIcon(bytes);
                    newImage = icon.getImage();
                    if (icon.getIconHeight() > 128 || icon.getIconWidth() > 128) {
                    newImage = newImage.getScaledInstance(-1, 128, Image.SCALE_SMOOTH);
                    }
                    icon = new ImageIcon(newImage);

                } catch (Exception e1) {
                    Log.error(e1);
                }

            } else {
                icon = SparkRes.getImageIcon(SparkRes.DEFAULT_AVATAR_32x32_IMAGE);
            }

            label.setIcon(icon);
            _avatarHoverWindow.pack();
            _avatarHoverWindow.invalidate();
            _avatarHoverWindow.validate();
            _avatarHoverWindow.repaint();

        } else {

            _avatarHoverWindow.setVisible(false);
        }

    }

    private void buildUI(final VCard vcard) {

        avatarImage.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent mouseEvent) {
                if (mouseEvent.getClickCount() == 2) {
                    SparkManager.getVCardManager().viewProfile(vcard.getJabberId(), avatarImage);
                }
            }

            final Timer timer = new Timer(500, new ActionListener() {
                public void actionPerformed(ActionEvent actionEvent) {
                    showAvatarBig(true, vcard);
                }
            });

            @Override
            public void mouseEntered(MouseEvent e) {
                super.mouseEntered(e);
                timer.start();
            }

            @Override
            public void mouseExited(MouseEvent e) {
                super.mouseExited(e);
                timer.stop();
            }

        });

        String firstName = vcard.getFirstName();
        if (firstName == null) {
            firstName = "";
        }

        String lastName = vcard.getLastName();
        if (lastName == null) {
            lastName = "";
        }

        final JLabel usernameLabel = new JLabel();
        usernameLabel.setHorizontalTextPosition(JLabel.LEFT);
        usernameLabel.setFont(new Font("Dialog", Font.BOLD, 15));
        usernameLabel.setForeground(Color.GRAY);
        if (ModelUtil.hasLength(firstName) && ModelUtil.hasLength(lastName)) {
            usernameLabel.setText(firstName + " " + lastName);
        }
        else {
            String nickname = SparkManager.getUserManager().getUserNicknameFromJID(jid);
            usernameLabel.setText(UserManager.unescapeJID(nickname));
        }

        final Icon icon = SparkManager.getChatManager().getIconForContactHandler(vcard.getJabberId());
        if (icon != null) {
            usernameLabel.setIcon(icon);
        }

        add(usernameLabel, new GridBagConstraints(1, 0, 4, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 0), 0, 0));

        // placing details in left side
        Map<String, String> details = new LinkedHashMap<String, String>();
		details.put("Department", vcard.getOrganizationUnit());
		details.put("Title", vcard.getField("TITLE"));
		details.put("Company", vcard.getOrganization());
		details.put("Locality", vcard.getAddressFieldWork("LOCALITY"));

		int position = 1;
		for (String key: details.keySet())
		{
	        if (ModelUtil.hasLength(details.get(key))) 
	        {
	            final JLabel keyLabel = new JLabel(key + ": ");
	            keyLabel.setFont(new Font("Dialog", Font.PLAIN, 10));
	            keyLabel.setForeground(Color.GRAY);
	            keyLabel.setHorizontalAlignment(JLabel.RIGHT);
	            add(keyLabel, new GridBagConstraints(1, position, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 0), 0, 0));
	            final JLabel detailLabel = new JLabel(details.get(key));
	            detailLabel.setFont(new Font("Dialog", Font.PLAIN, 11));
	            add(detailLabel, new GridBagConstraints(2, position, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 1, 0, 2), 0, 0));
	            position++;
	        }
		}

        // placing phones in right side
		Map<String, String> phones = new LinkedHashMap<String, String>();
		phones.put("Phone", vcard.getPhoneWork("VOICE"));
		phones.put("Mobile", vcard.getPhoneWork("CELL"));
		phones.put("Fax", vcard.getPhoneWork("FAX"));
		phones.put("FullJID", SparkManager.getUserManager().getFullJID(vcard.getJabberId()));
        phones.put("Resource", StringUtils.parseResource(SparkManager.getUserManager().getFullJID(vcard.getJabberId())));
        
		position = 1;
		for (String key: phones.keySet())
		{
	        if (ModelUtil.hasLength(phones.get(key))) 
	        {
	            final JLabel keyLabel = new JLabel(key + ": ");
	            keyLabel.setFont(new Font("Dialog", Font.PLAIN, 10));
	            keyLabel.setForeground(Color.GRAY);
	            keyLabel.setHorizontalAlignment(JLabel.RIGHT);
	            add(keyLabel, new GridBagConstraints(3, position, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(0, 20, 0, 0), 0, 0));
	            final JLabel detailLabel = new JLabel(phones.get(key));
	            detailLabel.setFont(new Font("Dialog", Font.PLAIN, 11));
	            add(detailLabel, new GridBagConstraints(4, position, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 1, 0, 2), 0, 0));
	            position++;
	        }
		}
    }
}
